import {PluginCommand} from "./PluginCommand";
import {ElementType, GeomType} from "../modeling/TypeDefine";
import {Direction, Matrix4, Point, ScriptVariableType} from "../../nodeApp/static/lib/crowncad-plugin-sdk-0.0.1";
import {Vector3} from "three";
import {request} from "../util/Request";

class HeatAndSoundInsulationCommand extends PluginCommand {
  constructor() {
    super();
  }

  async executeConfirm(params) {
    if (params.frames.length < 2 || params.longerons.length < 2) {
      return;
    }
    //删除框间隔热隔声数据
    await this.deleteData();
    //曲面裁剪后生成新的曲面
    let trimSurfaceResult = await this.createSurface(params);
    //计算后续用到的参数值（长桁间的距离，交线等）
    await this.calculateParametersValue(params, trimSurfaceResult);
    if (params.frameLength == 0 || params.longeronLength == 0 || !trimSurfaceResult) {
      return;
    }

    //二维展开图创建
    await this.drawSketch(params);
    //三维模型创建
    await this.create3DModel(trimSurfaceResult, params);
    this.closeActiveCmd();
  }
  //删除数据
  async deleteData() {
    let res = await this.query.getFeaturesByNames(["复制曲面"]);
    if (res.data?.features.length > 0) {
      let copyFeature = res.data?.features[0];
      if (!copyFeature) {
        return;
      }
      let result = await this.toolQuery.getAllFeatures();
      let deleteFeatureIds = [];
      if (result?.data && result?.data.length > 0) {
        result?.data.forEach(feature => {
          if (feature.id >= copyFeature.id) {
            deleteFeatureIds.push(feature.id);
          }
        })
      }
      if (deleteFeatureIds.length > 0) {
        await this.command.common.deleteFeatureIncrement({featureIds: deleteFeatureIds});
      }
    }
  }
  //截剪曲面
  async createSurface(params) {
    if (params.surfaces.length < 1 || params.frames.length < 2 || params.longerons.length < 2) {
      return;
    }
    let surf = params.surfaces[0];
    //复制并偏移曲面,这个接口有问题，
    // 如果使用了此接口，对于个别模型失败之后，copySurface接口也会失效，其他命令也无法使用copySurface，需要清空浏览器缓存才可以使用。什么神奇操作
    //let copySurface = await this.command.surface.offsetSurfaceIncrement({surfaceIds: [surf.id], distance: params.longeronHeight}, "复制曲面");
    //复制曲面
    let copySurface = await this.copySurface(surf);
    //筛选出面元素

    let faceElement = await this.getFace(copySurface);
    if (!faceElement) {
      return;
    }
    //通过框裁剪曲面
    let trimSurfaceRes = await this.trimSurface(faceElement, params.frames);
    //通过长桁裁剪曲面
    //重新查找裁剪后的曲面
    let trimFace = await this.getFace(trimSurfaceRes);
    if (!trimFace) {
      return;
    }
    //对长桁进行排序
    params.longerons = this.queuePlaneList(params.longerons);
    let longeronsLen = params.longerons.length;
    if (longeronsLen < 2) {
      return;
    }
    let trimElements = [params.longerons[0], params.longerons[longeronsLen - 1]]
    let result = await this.trimSurface(trimFace, trimElements);
    await this.event.clearPreview();
    return result;
  }
  //曲面复制
  async copySurface(surface){
    //拷贝曲面
    let surfaceTemp = surface;
    //复制后对复制曲面进行操作
    let copySurface = await this.command.surface.copySurfaceIncrement({surfaceIds: [surfaceTemp.id], instanceIds: [0]}, "复制曲面");

    let featureId = this.getFeatureId(copySurface);
    await this.setFeatureVisible(featureId,false);
    return copySurface;
  }
  async trimSurface(surface, selectElements) {
    if (!surface || !selectElements || selectElements.length < 2) {
      return;
    }
    let element1 = selectElements[0];
    let element2 = selectElements[1];
    let pos1, pos2, normal1, normal2, entityId1, entityId2;
    if (element1.type === ElementType.FACE) {
      pos1 = element1?.params?.position;
    } else if (element1.type === ElementType.DATUMPLANE) {
      pos1 = element1?.params?.origin;
    }
    normal1 = element1?.params?.normal;
    entityId1 = element1?.params?.entityRefId;

    if (element2.type === ElementType.FACE) {
      pos2 = element2?.params?.position;
    } else if (element2.type === ElementType.DATUMPLANE) {
      pos2 = element2?.params?.origin;
    }
    normal2 = element2?.params?.normal;
    entityId2 = element2?.params?.entityRefId;

    if (!pos1 || !pos2 || !normal1 || !normal2 || !entityId1 || !entityId2) {
      return;
    }

    let result = await this.query.getEntitiesByIds([entityId1, entityId2]);
    let trimElement = [];
    let surfaceElement = [];
    surfaceElement.push(surface);
    if (result && result?.data?.entities.length > 1) {
      let entity1 = result?.data?.entities[0];
      let entity2 = result?.data?.entities[1];
      trimElement.push(entity1);
      trimElement.push(entity2);
    }
    // let elementsRes = await this.query.getElementsByFeatureNames([ '拉伸曲面6']);
    // let elements = elementsRes?.data?.elements;
    // if (elements && elements.length > 0) {
    //   elements.forEach(element => {
    //     if (element.type === ElementType.FACE) {
    //       surfaceElement.push(element);
    //     }
    //   })
    // }
    let params = {
      trimElement: trimElement,
      surfaceElement: surfaceElement,
    }
    let previewResult = await this.toolQuery.executePreviewTrimSurface(params);
    let keepTags = [];
    let newSrfDataArray, oldSrfDataArray;
    if (previewResult) {
      let position1 = new THREE.Vector3(pos1.x, pos1.y, pos1.z);
      let position2 = new THREE.Vector3(pos2.x, pos2.y, pos2.z);
      let elementNormal1 = new THREE.Vector3(normal1.x, normal1.y, normal1.z);
      let elementNormal2 = new THREE.Vector3(normal2.x, normal2.y, normal2.z);

      newSrfDataArray = previewResult?.data?.elements?.newSrfData;
      oldSrfDataArray = previewResult?.data?.elements?.oldSrfData;
      // console.log(newSrfDataArray);
      // console.log(oldSrfDataArray);
      let lastLength = 0;
      let index = -1;
      for (let i = 0; i < newSrfDataArray?.length; i++) {
        let boxCenter = await this.toolQuery.getMiddleElementBoxCenterPoint(newSrfDataArray[i]);
        let vector1 = position1.clone().sub(boxCenter?.data);
        let vector2 = position2.clone().sub(boxCenter?.data);
        let dir1 = vector1.clone().dot(elementNormal1);
        let dir2 = vector2.clone().dot(elementNormal2);
        let dir3 = elementNormal1.clone().dot(elementNormal2);
        if ((dir3 > 0 && dir1 * dir2 < 0) || (dir3 < 0 && dir1 * dir2 > 0)) {
          let length = vector1.length();
          if (lastLength === 0) {
            lastLength = length;
            index = i;
            keepTags.push(1);
          } else {
            if (lastLength < length) {
              keepTags.push(0);
            } else {
              keepTags[index] = 0;
              lastLength = length;
              index = i;
              keepTags.push(1);
            }
          }
        } else {
          keepTags.push(0);
        }
      }
    }
    //执行裁剪曲面
    let limitIds = [];
    trimElement.forEach(entity => {
      limitIds.push(entity.id);
    })
    let surfaceIds = [];
    surfaceElement.forEach(ele => {
      surfaceIds.push(ele.id);
    })
    let surfaceResult = await this.command.surface.trimSurfaceIncrement({
      limitIds: limitIds,
      surfaceIds: surfaceIds,
      keepMode: 1,
      keepTags: keepTags,
      oldSurfaceIds: oldSrfDataArray,
      newSurfaceIds: newSrfDataArray,
    })
    return surfaceResult;
  }
  getFeatureId(result) {
    let currentFeature = result?.data?.modelData?.currentFeature;
    if (currentFeature && currentFeature.length > 0) {
      return currentFeature[0].id;
    }
  }
  async getFace(result) {
    let face;
    result?.data?.modelData?.data?.addElements?.forEach(ele => {
      if (ele.type === ElementType.FACE || ele.type === ElementType.SURFACE) {
        face = ele;
        return face;
      }
    })
    return face;
  }
  async getLine(result) {
    let line;
    let addElements = result?.data?.modelData?.data?.addElements;
    addElements?.forEach(ele => {
      if (ele.type === ElementType.CURVE) {
        line = ele;
      }
    })
    return line;
  }
  //三维模型创建
  async create3DModel(trimSurfaceResult, params) {
    //第一个长桁面的位置及法向
    let posVec = this.getPosition(params.longerons[0]);
    let normal = params.longerons[0]?.params?.normal;
    let normalVec = new THREE.Vector3(normal.x, normal.y, normal.z);
    let featureId = this.getFeatureId(trimSurfaceResult);
    //隐藏曲面
    let entitiesRes = await this.toolQuery.getEntitiesByFeatureId(featureId);
    if (entitiesRes && entitiesRes?.data?.entities?.length > 0) {
      let entityId = entitiesRes?.data?.entities[0].id;
      await this.command.common.setEntityVisibleIncrement({entityIds:[entityId], status: 0});
    }
    let eleRes = await this.query.getElementsByFeatureId(featureId);
    let elements = eleRes?.data?.elements;
    let startPoint, endPoint;//长桁面上的起始位置三维点
    let curve;//后面做拉伸凸台时用到的引导曲线
    for (let i = 0; i < elements?.length; i++) {
      if (elements[i].type === ElementType.EDGE) {
        if (elements[i]?.params?.type === GeomType.LINE) {
          let startPnt = elements[i].params?.startPoint;
          let endPnt = elements[i].params?.endPoint;
          let startPntVec = new THREE.Vector3(startPnt[0], startPnt[1], startPnt[2]);
          let endPntVec = new THREE.Vector3(endPnt[0], endPnt[1], endPnt[2]);
          let projectStartPnt = this.pointProject(normalVec, posVec, startPntVec);
          let projectEndPnt = this.pointProject(normalVec, posVec, endPntVec);
          //判断点是否在长桁基准面上
          let length1 = startPntVec.clone().sub(projectStartPnt).length().toFixed(5);
          let length2 = endPntVec.clone().sub(projectEndPnt).length().toFixed(5);
          if (length1 == 0 && length2 == 0 && !startPoint && !endPoint) {
            startPoint = startPntVec;
            endPoint = endPntVec;
          }
        } else if (!curve) {
          curve = elements[i];
        }
      }
    }
    if (!curve || !startPoint || !endPoint) {
      return;
    }

    let startToEndLength = endPoint.clone().sub(startPoint).length();
    params.startToEndLength = startToEndLength;

    //计算隔框的截面草图
    let sectionPointList = this.calculateSketchPoints(params);

    //创建草图
    let sketchPlaneId = params.longerons[0].id;

    //判断当前选定的草图平面上，引导线哪个端点在草图平面上
    let startOrEndOnPlane = this.getStartOrEndOnPlane(curve,posVec,normalVec);

    //创建具有原点和上方向以及法向的草图平面
    //需要创建一个原点然后生成具有指定原点的草图
    let originPointId = await this.createPointByCurve(curve,startOrEndOnPlane * 100);

    let yyDirection = new Direction();
    //Y向无论何时都应该指向内
    yyDirection.setPoint(new Point(0,0,0),new Point(params.inwardDirection.x,params.inwardDirection.y,params.inwardDirection.z)); //构造方法啥也不是

    //通过航向进行矫正后的草图法向
    let sketchNormalModify = (new THREE.Vector3().crossVectors(params.dirCourse,params.inwardDirection)).normalize();
    let reverseNormal = 0;
    if(normalVec.clone().dot(sketchNormalModify) < 0){
      reverseNormal = 1;
    }

    //如果startPoint指向endPoint的方向与航向相反，应该再反向
    let value = (endPoint.clone().sub(startPoint)).dot(params.dirCourse);
    if(value < 0){
      reverseNormal = 0 ? 1 : 0;
    }

    //创建一个以左侧点为基准，以起始长桁站位法向为法向，内方向为Y向的草图
    await this.command.sketch.createSketchIncrement({sketchName: '',
      datumId: sketchPlaneId,
      originRefId:originPointId,
      yDirection:yyDirection,
      reverseNormal:reverseNormal});

    //创建所有草图折线
    for(let pointIndex = 0;pointIndex < sectionPointList.length;pointIndex++)
    {
      let startPoint = sectionPointList[pointIndex];
      let endPoint;
      if(pointIndex === sectionPointList.length - 1){
        endPoint = sectionPointList[0];
      }else{
        endPoint = sectionPointList[pointIndex + 1];
      }
      await this.createSketchLine({
        startPoint: new Point(this.dealValue(startPoint.x), this.dealValue(startPoint.y)),
        endPoint: new Point(this.dealValue(endPoint.x), this.dealValue(endPoint.y))
      });
    }

    let sketch = await this.command.sketch.exitSketchIncrement();

    //进行扫描凸台创建
    let sketchFeatureId = this.getFeatureId(sketch);
    let res = await this.toolQuery.getEntitiesByFeatureId(sketchFeatureId);
    let sweepSolid;
    if (res && res?.data?.entities?.length > 0) {
      let entityId = res?.data?.entities[0].id;
      //扫描凸台
      sweepSolid = await this.command.solid.sweepIncrement({
        sweepType: 0,
        sweepProfile: entityId,
        sweepPath: [curve.id],
        sweepDirection: -1,
      }, "")
    }

    //加强长桁
    if (params.reinforcedLongerons.length > 0) {
      await this.createReinforcedLongerons(params, sweepSolid);
    }

    return sweepSolid;
  }
  calculateSketchPoints(params){
    let solidThickness = parseFloat(params.thickness);//实体厚度
    let flangingHeight = parseFloat(params.flangingHeight);//翻边高度
    let flangingThickness1 = parseFloat(params.flangingThickness1);//翻边厚度1
    let flangingThickness2 = parseFloat(params.flangingThickness2);//翻边厚度2
    let longerousHeight = parseFloat(params.longeronHeight); //长桁高度
    let width = params.startToEndLength;

    let points = [];
    let point1 = new THREE.Vector3(0, longerousHeight);
    let point2 = new THREE.Vector3(point1.x + width, point1.y);
    if (params.flanging) {
      //以左下角为基准点开始创建，逆时针计算
      let point3 = new THREE.Vector3(point2.x, point2.y + solidThickness + flangingHeight);
      let point4 = new THREE.Vector3(point3.x - flangingThickness2, point3.y);
      let point5 = new THREE.Vector3(point4.x, point4.y - flangingHeight);
      let point6 = new THREE.Vector3(point5.x + flangingThickness1 + flangingThickness2 - width, point5.y);
      let point7 = new THREE.Vector3(point6.x, point6.y + flangingHeight);
      let point8 = new THREE.Vector3(point1.x, point1.y + solidThickness + flangingHeight);
      points = [point1, point2, point3, point4, point5, point6, point7, point8];
    } else {
      let point3 = new THREE.Vector3(point2.x, point2.y + solidThickness);
      let point4 = new THREE.Vector3(point1.x, point1.y + solidThickness);
      points = [point1, point2, point3, point4];
    }
    return points;
  }
  calculateReinforcedPoints(params){
    let drawPoints = [];
    let thickness =  parseFloat(params.thickness);
    let spanOffset = parseFloat(params.spanOffset);//蒙皮处沿展向偏移值
    let headingOffset = parseFloat(params.headingOffset);//近内饰处沿航向偏移值
    // headingOffset -= parseFloat(params.longeronHeight);
    let headingOffsetLeft = parseFloat(params.headingOffsetLeft);//近内饰处沿航向偏移值左
    let headingOffsetRight = parseFloat(params.headingOffsetRight);//近内饰处沿航向偏移值右
    let longeronH = parseFloat(params.longeronHeight);    //长桁高度
    drawPoints.splice(0);
    drawPoints.push(new Point(-spanOffset, longeronH));
    drawPoints.push(new Point(spanOffset, longeronH));
    drawPoints.push(new Point(headingOffsetRight, headingOffset));
    drawPoints.push(new Point(-headingOffsetLeft, headingOffset));

    let pointList = this.getOffsetPointList(drawPoints, thickness);
    if (pointList.length === 4) {
      pointList[0].y += 5;
      pointList[3].y += 5;
    }
    drawPoints[0].y -= 3;
    drawPoints[1].y -= 3;

    // let allDrawPoints = drawPoints;
    // for(let i = pointList.length - 1 ;i >= 0;i--){
    //   allDrawPoints.push(pointList[i]);
    // }
    return {drawPoints:drawPoints,allDrawPoints:pointList};
  }
  async create3DPoint(pos) {
    await this.command.sketch.create3DSketch({sketchName: ""});
    await this.command.sketch.create3DPoint({X: pos.x, Y: pos.y, Z: pos.z});
    await this.command.sketch.exitSketch();
    let commandRes = await this.command.executeIncrementCommand(this.command.commandScript);
    this.command.clearCommand();
    let pointFeatureId = this.getFeatureId(commandRes);
    let pointElement = await this.getPointByFeatureId(pointFeatureId);
    let pointId = pointElement?.id;
    return pointId;
  }
  async getPointByFeatureId(featureId) {
    let pointElementsRes = await this.query.getElementsByFeatureId(featureId);
    let pointElements = pointElementsRes?.data?.elements;
    let pointEle;
    if (pointElements) {
      for (let i = 0; i < pointElements.length; i++) {
        if (pointElements[i].type === ElementType.POINT) {
          pointEle = pointElements[i];
          break;
        }
      }
    }
    return pointEle;
  }
  async createReinforcedLongerons(params, sweepSolid) {
    let resultValue = sweepSolid;
    for (let i = 0; i < params.reinforcedLongerons.length; i++) {
      let longeron = params.reinforcedLongerons[i];
      resultValue = await this.createReinforcedLongeron(longeron, params, resultValue);
    }
  }
  async createReinforcedLongeron(longeron, params, resultValue){
    //交线
    let startPnt = longeron?.intersectLine?.params?.startPoint;
    let endPnt = longeron?.intersectLine?.params?.endPoint;
    startPnt = this.getThreeVector3(startPnt);
    endPnt = this.getThreeVector3(endPnt);
    let startToEnd = endPnt.clone().sub(startPnt);

    //框平面参数
    let frameOrigin = this.getThreeVector3(params.frames[0].params.origin);
    let frameNormal = this.getThreeVector3(params.frames[0].params.normal);

    //保持起点指向终点方向与航向一致
    let value = startToEnd.dot(params.dirCourse);
    if(value < 0){
      let temp = endPnt.clone();
      endPnt = startPnt.clone();
      startPnt = temp.clone();
    }

    //计算当前长桁站位的法向,
    let curLongeronInDir= longeron?.params?.normal;
    let dirLongeronNormal = new Vector3(curLongeronInDir.x, curLongeronInDir.y, curLongeronInDir.z);
    //当前长桁点的向内/外方向，即当前加强隔热隔声草图的上/下方向
    let dirIn = new THREE.Vector3().crossVectors(params.dirCourse,dirLongeronNormal);

    let lineStart = this.getThreeVector3(longeron.intersectLine.params.startPoint);
    let lineEnd = this.getThreeVector3(longeron.intersectLine.params.endPoint);

    let pointOrigin = lineStart;
    //点到平面的距离
    let pointToPlanePoint = lineStart.clone().sub(frameOrigin);
    let disPointToPlane = Math.abs(pointToPlanePoint.clone().dot(frameNormal)) / (frameNormal.length());
    if(disPointToPlane > 0.001){
      pointOrigin = lineEnd;
      startToEnd.negate();
    }

    let originPointId = await this.create3DPoint(pointOrigin);

    let yyDirection = new Direction();
    //Y向无论何时都应该指向内
    yyDirection.setPoint(new Point(0,0,0),new Point(dirIn.x,dirIn.y,dirIn.z)); //构造方法啥也不是

    //计算隔框的截面草图
    let pointsInfo = this.calculateReinforcedPoints(params);

    //创建一个草图，用于拉伸合并
    await this.command.sketch.createSketchIncrement({sketchName: '',
      datumId: params.frames[0].id,
      originRefId:originPointId,
      yDirection:yyDirection,
      reverseNormal:0});

    //创建所有草图折线
    for(let pointIndex = 0;pointIndex < pointsInfo.allDrawPoints.length;pointIndex++)
    {
      let startPoint = pointsInfo.allDrawPoints[pointIndex];
      let endPoint;
      if(pointIndex === pointsInfo.allDrawPoints.length - 1){
        endPoint = pointsInfo.allDrawPoints[0];
      }else{
        endPoint = pointsInfo.allDrawPoints[pointIndex + 1];
      }
      await this.createSketchLine({
        startPoint: new Point(this.dealValue(startPoint.x), this.dealValue(startPoint.y)),
        endPoint: new Point(this.dealValue(endPoint.x), this.dealValue(endPoint.y))
      });
    }
    let sketch1 = await this.command.sketch.exitSketchIncrement();

    //创建一个草图,用于拉伸切除
    await this.command.sketch.createSketchIncrement({sketchName: '',
      datumId: params.frames[0].id,
      originRefId:originPointId,
      yDirection:yyDirection,
      reverseNormal:0});

    //创建所有草图折线,用于切除
    for(let pointIndex = 0;pointIndex < pointsInfo.drawPoints.length;pointIndex++)
    {
      let startPoint = pointsInfo.drawPoints[pointIndex];
      let endPoint;
      if(pointIndex === pointsInfo.drawPoints.length - 1){
        endPoint = pointsInfo.drawPoints[0];
      }else{
        endPoint = pointsInfo.drawPoints[pointIndex + 1];
      }
      await this.createSketchLine({
        startPoint: new Point(this.dealValue(startPoint.x), this.dealValue(startPoint.y)),
        endPoint: new Point(this.dealValue(endPoint.x), this.dealValue(endPoint.y))
      });
    }

    let sketch2 = await this.command.sketch.exitSketchIncrement();

    //拉伸凸台方向
    let direction = new Direction();
    direction.setPoint(new Point(0,0,0), new Point(startToEnd.x, startToEnd.y, startToEnd.z));

    //拉伸凸台
    let entityId1 = await this.getEntityIdByFeatureRes(sketch1);
    let solid3DEntityId = await this.getEntityIdByFeatureRes(resultValue);
    let extrudeRes;
    if (entityId1 && solid3DEntityId) {
      extrudeRes = await this.command.solid.extrudeIncrement({
        sketch: entityId1,
        height1: startToEnd.length(),
        directionType: 1,
        direction: direction,
        mergeType: 1,
        mergeSolids: [solid3DEntityId],
      }, '');
    }

    let entityId2 = await this.getEntityIdByFeatureRes(sketch2);
    let cutSolidId = await this.getEntityIdByFeatureRes(extrudeRes);
    let extrudeCutRes = await this.command.solid.extrudeCutIncrement({
      sketch: entityId2,
      directionType: 1,
      direction: direction,
      height1: startToEnd.length(),
      cutSolids: [cutSolidId],
    }, '');
    return extrudeCutRes;
  }
  //计算长桁与曲面交线起点
  async createIntersectPoint(longeron, params, resultValue) {
    let origin = this.getPosition(longeron);
    let normal= longeron?.params?.normal;
    let normalVec = new Vector3(normal.x, normal.y, normal.z);
    //设置草图原点，解决草图显示有偏移的问题
    let originPointId = await this.create3DPoint(origin);
    //交线
    let startPnt = longeron?.intersectLine?.params?.startPoint;
    let endPnt = longeron?.intersectLine?.params?.endPoint;
    let startPoint = this.newVectorPnt(startPnt);
    let endPoint = this.newVectorPnt(endPnt);
    //将三维点转换成二维点
    let s2D = this.convertPoint3DToPoint2D(longeron, startPoint);
    let e2D = this.convertPoint3DToPoint2D(longeron, endPoint);
    let startPnt2D = new Point(s2D.x, s2D.y);
    if ((s2D.x == e2D.x && s2D.y > e2D.y) || (s2D.y == e2D.y && s2D.x > e2D.x)) {
      startPnt2D = new Point(e2D.x, e2D.y);
    }
    //创建草图线
    let xDirection = longeron?.params?.xDirection;
    let yDir = new THREE.Vector3().crossVectors(normalVec, xDirection);
    let yDirection = new Direction();
    yDirection.setPoint(new Point(0, 0, 0), new Point(yDir.x, yDir.y, yDir.z));
    if (originPointId) {
      await this.command.sketch.createSketchIncrement({sketchName: '', datumId: longeron.id, originRefId: originPointId, yDirection: yDirection});
      await this.command.sketch.createPointIncrement({x: startPnt2D.x, y: startPnt2D.y});//创建交点
      let sketchRes = await this.command.sketch.exitSketchIncrement();
      let sketchFeatureId = this.getFeatureId(sketchRes);
      let pointEle = await this.getPointByFeatureId(sketchFeatureId);
      // let pointPos = pointEle?.params?.position;
      // let posVec = new Vector3(pointPos.x, pointPos.y, pointPos.z);
      let frameNormal = params.frameNormal;
      yDir = new THREE.Vector3().crossVectors(frameNormal, normalVec);
      yDirection = new Direction();
      let dirTmp = yDir.clone().dot(params.inwardDirection);
      if (dirTmp < 0) { //方向相反
        yDirection.setPoint(new Point(yDir.x, yDir.y, yDir.z), new Point(0, 0, 0));
      } else {
        yDirection.setPoint(new Point(0, 0, 0), new Point(yDir.x, yDir.y, yDir.z));
      }
      if (pointEle?.id) {
        let drawPoints = [];
        let thickness =  parseFloat(params.thickness);
        let spanOffset = parseFloat(params.spanOffset);//蒙皮处沿展向偏移值
        let headingOffset = parseFloat(params.headingOffset);//近内饰处沿航向偏移值
        headingOffset -= parseFloat(params.longeronHeight);
        let headingOffsetLeft = parseFloat(params.headingOffsetLeft);//近内饰处沿航向偏移值左
        let headingOffsetRight = parseFloat(params.headingOffsetRight);//近内饰处沿航向偏移值右
        drawPoints.splice(0);
        drawPoints.push(new Point(-spanOffset, 0));
        drawPoints.push(new Point(spanOffset, 0));
        drawPoints.push(new Point(headingOffsetRight, headingOffset));
        drawPoints.push(new Point(-headingOffsetLeft, headingOffset));
        let pointList = this.getOffsetPointList(drawPoints, thickness);

        let posTmp = pointEle?.params?.position;
        let posVec = new Vector3(posTmp.x, posTmp.y, posTmp.z);
        let len = this.getDistancePointToPlane(posVec, params.frames[1]);
        let datumId = params.frames[0]?.id;
        if (len == 0) {
          datumId = params.frames[1]?.id;
        }

        await this.command.sketch.createSketchIncrement({sketchName: '', datumId: datumId, originRefId: pointEle?.id, yDirection: yDirection});
        await this.createLine(drawPoints);
        let sketchRes1 = await this.command.sketch.exitSketchIncrement();
        // let xValue = Math.sqrt(((headingOffsetLeft - spanOffset) / headingOffset * thickness) ** 2 + thickness ** 2);
        // let yValue = 0;
        // drawPoints.push(new Point(-xValue, yValue + 2));
        // drawPoints.push(new Point(xValue, yValue + 2));
        // xValue = spanOffset + thickness + ((headingOffsetRight - spanOffset) / headingOffset * (headingOffset + thickness));
        // yValue = headingOffset + thickness;
        // drawPoints.push(new Point(xValue, yValue));
        // xValue = spanOffset + thickness + ((headingOffsetLeft - spanOffset) / headingOffset * (headingOffset + thickness));
        // drawPoints.push(new Point(-xValue, yValue));
        if (pointList.length === 4) {
          pointList[0].y += 2;
          pointList[3].y += 2;
        }
        await this.command.sketch.createSketchIncrement({sketchName: '', datumId: datumId, originRefId: pointEle?.id, yDirection: yDirection});
        await this.createLine(pointList);
        let sketchRes2 = await this.command.sketch.exitSketchIncrement();
        //拉伸凸台
        let direction = new Direction();
        direction.setPoint(new Point(startPoint.x, startPoint.y, startPoint.z), new Point(endPoint.x, endPoint.y, endPoint.z));
        let entityId = await this.getEntityIdByFeatureRes(sketchRes2);
        let solid3DEntityId = await this.getEntityIdByFeatureRes(resultValue);
        let extrudeRes;
        if (entityId && solid3DEntityId) {
          extrudeRes = await this.command.solid.extrudeIncrement({
            sketch: entityId,
            height1: params.frameLength,
            directionType: 1,
            direction: direction,
            mergeType: 1,
            mergeSolids: [solid3DEntityId],
          }, '');
        }

        //拉伸切除
        let entityId1 = await this.getEntityIdByFeatureRes(sketchRes1);
        if (entityId1 && extrudeRes) {
          let cutSolidId = await this.getEntityIdByFeatureRes(extrudeRes);
          let extrudeCutRes = await this.command.solid.extrudeCutIncrement({
            sketch: entityId1,
            directionType: 1,
            direction: direction,
            height1: params.frameLength,
            cutSolids: [cutSolidId],
          }, '');
          return extrudeCutRes;
        }
      }
    }
  }

  //点到点与法线组成的平面的距离
  getDistancePointToPlane(point,plane){
    let planePoint = plane?.params?.origin;
    let planeDir = plane?.params?.normal;
    let pntVec = new Vector3(planePoint.x, planePoint.y, planePoint.z);
    let dirVec = new Vector3(planeDir.x, planeDir.y, planeDir.z);
    //点到平面的距离
    let pointToPlanePoint = pntVec.clone().sub(point);
    let disPointToPlane = Math.abs(pointToPlanePoint.clone().dot(dirVec)) / (dirVec.length());
    return disPointToPlane;
  }

  newVectorPnt(pnt) {
    if (Math.abs(pnt[0]) < 0.0001) {
      pnt[0] = 0;
    }
    if (Math.abs(pnt[1]) < 0.0001) {
      pnt[1] = 0;
    }
    if (Math.abs(pnt[2]) < 0.0001) {
      pnt[2] = 0;
    }
    let retVector = new Vector3(pnt[0], pnt[1], pnt[2]);
    return retVector;
  }

  getOffsetPointList(pointList,dis){
    let pointListNew = [];
    let len = pointList.length;
    for(let i = 0;i < len;i++){
      let lineDis1 = dis;
      let lineDis2 = dis;
      let point2No = i + 1;
      let point3No = i + 2;
      if(point2No >= pointList.length){
        point2No -= pointList.length;
      }
      if(point3No >= pointList.length){
        point3No -= pointList.length;
      }
      if (i === 0) {
        lineDis1 = 0;
      }
      if (i === len - 1) {
        lineDis2 = 0;
      }

      let point1 = new Vector3(pointList[i].x, pointList[i].y);
      let point2 = new Vector3(pointList[point2No].x, pointList[point2No].y);
      let point3 = new Vector3(pointList[point3No].x, pointList[point3No].y);

      let line1 = this.getOffsetLine(point1,point2,lineDis1);
      let line2 = this.getOffsetLine(point2,point3,lineDis2);

      let intersectPoint = this.getIntersectPoint2(line1.point1,line1.point2,line2.point1,line2.point2);
      let pnt = new Point(intersectPoint.x, intersectPoint.y, intersectPoint.z);
      pointListNew.push(pnt);
    }
    return pointListNew;
  }

  //两条线求交点
  getIntersectPoint2(point11,point12,point21,point22){
    //判断两个点不平行
    let dir1 = point12.clone().sub(point11);
    let dir2 = point22.clone().sub(point21);
    dir1.normalize();
    dir2.normalize();

    let dotValue = dir1.clone().dot(dir2);
    if(Math.abs(dotValue) > 0.99999){
      return;
    }

    let a = point12.y - point11.y;
    let b = point11.x - point12.x;
    let c = point11.x * point12.y - point12.x * point11.y;
    let d = point22.y - point21.y;
    let e = point21.x - point22.x;
    let f = point21.x * point22.y - point22.x * point21.y;

    let denominator = b * d - a * e;
    let x = (b * f - e * c) / denominator;
    let y = (d * c - a * f) / denominator;
    return new THREE.Vector3(x,y);
  }

  //在空间中，以第一个点到第二个点方向的顺时方向偏移一定距离形成新的线,normal为空时为(0,0,1),即二维
  getOffsetLine(point1,point2,dis,normal = null){
    if(!normal){
      normal = new THREE.Vector3(0,0,1);
    }

    //point1，point2，需要和normal垂直
    let dir = point2.clone().sub(point1);
    dir.normalize();
    let value = dir.clone().dot(normal);
    if(Math.abs(value) > 0.001){
      return;
    }

    //获取顺向偏移方向
    let offsetDir = new THREE.Vector3().crossVectors(dir,normal);
    offsetDir.normalize();

    let offsetVec = offsetDir.multiplyScalar(dis);

    let newPoint1 = point1.clone().add(offsetVec);
    let newPoint2 = point2.clone().add(offsetVec);
    let param = {point1:newPoint1,point2:newPoint2};
    return param;
  }

  async getEntityIdByFeatureRes(featureRes) {
    let featureId = this.getFeatureId(featureRes);
    let res = await this.query.getEntitiesByFeatureIds([featureId]);
    let entities = res?.data?.entities;
    if (entities && entities.length > 0) {
      return entities[0].id;
    }
  }
  //框间二维展开图
  async drawSketch(params) {
    let sketch = this.command.sketch;
    //创建二维展开图
    let frameId = params.frames[0].id;
    await sketch.createSketchIncrement({sketchName: '', datumId: frameId});
    //绘制内矩形框
    await this.drawInnerRectFrame(params);
    //绘制长桁虚线
    await this.drawLongeronLine(params);
    //外框
    await this.drawOutFrame(params);
    //绘制孔位点
    await this.drawHolePoints(params);
    //绘制开叉
    await this.drawJagLines(params);
    //生成窗户
    await this.drawWindow(params);
    await sketch.exitSketchIncrement();
  }
  //计算二维展开图中用到的参数
  async calculateParametersValue(params, trimSurfaceResult) {
    //框站位
    let frameNormal = params.frames[0]?.params?.normal;
    let frameNormalVec = new THREE.Vector3(frameNormal.x, frameNormal.y, frameNormal.z);
    let longeronNormal = params?.longerons[0]?.params?.normal;
    let longeronNormalVec = new THREE.Vector3(longeronNormal.x, longeronNormal.y, longeronNormal.z);
    let framePos = this.getPosition(params?.frames[0]);
    let longeronPos = this.getPosition(params?.longerons[0]);
    if (!frameNormalVec || !longeronNormal) {
      return;
    }

    params.framePos = framePos;
    params.frameNormal = frameNormalVec;
    params.longeronPos = longeronPos;
    params.longeronNormal = longeronNormalVec;

    // let frameLength = 0;//两个框间的距离
    //长桁站位的位置
    // let featureId = this.getFeatureId(trimSurfaceResult);
    // let eleRes = await this.query.getElementsByFeatureId(featureId);
    // let elements = eleRes?.data?.elements;
    // for (let i = 0; i < elements?.length; i++) {
    //   if (elements[i].type === ElementType.EDGE) {
    //     let startPnt = elements[i].params?.startPoint;
    //     let endPnt = elements[i].params?.endPoint;
    //     let startPntVec = new THREE.Vector3(startPnt[0], startPnt[1], startPnt[2]);
    //     let endPntVec = new THREE.Vector3(endPnt[0], endPnt[1], endPnt[2]);
    //     let length = endPntVec.clone().sub(startPntVec).length().toFixed(5);
    //     if (length == 0) {
    //       continue;
    //     }
    //     if (elements[i]?.params?.type === GeomType.LINE) {
    //       if (frameLength == 0) {
    //         frameLength = length;
    //         break;
    //       }
    //     }
    //   }
    // }
    let frameOrigin2 = this.getPosition(params.frames[1]);
    if (frameOrigin2) {
      let pntProject = this.pointProject(frameNormalVec, framePos, frameOrigin2)
      if (pntProject) {
        params.frameLength = pntProject.clone().sub(frameOrigin2).length();
      }
    }
    // params.frameLength = frameLength;

    //计算长桁间的交线及相邻长桁的距离
    let planeList = await this.computeLongeronsLength(params, trimSurfaceResult);
    params.longeronPlaneList = planeList;
    await this.computeInwardDirection(params);
  }
  //计算向内方向
  computeInwardDirection(params) {
    let frameNormal = params.frames[0]?.params?.normal;
    let frameNormalVec = new THREE.Vector3(frameNormal.x, frameNormal.y, frameNormal.z);

    let longeronNormal0 = params.longerons[0]?.params?.normal;
    let longeronNormalVec0 = new THREE.Vector3(longeronNormal0.x, longeronNormal0.y, longeronNormal0.z);
    let longeronNormal1 = params.longerons[1]?.params?.normal;
    let longeronNormalVec1 = new THREE.Vector3(longeronNormal1.x, longeronNormal1.y, longeronNormal1.z);
    let longeronOrigin1 = params.longerons[1]?.params?.origin;
    let longeronOriginVec1 = new THREE.Vector3(longeronOrigin1.x, longeronOrigin1.y, longeronOrigin1.z);

    let intersectLine = params.longerons[0].intersectLine;

    let crossVec = new THREE.Vector3().crossVectors(frameNormalVec, longeronNormalVec0);
    let crossVec2 =  new THREE.Vector3().crossVectors(longeronNormalVec0, frameNormalVec);
    if (intersectLine) {
      let startPnt = intersectLine?.params?.startPoint;
      if (startPnt) {
        let startPntVec = new THREE.Vector3(startPnt[0], startPnt[1], startPnt[2]);
        let endPntVec = crossVec.clone().add(startPntVec);
        //投影到第二个长桁的距离
        let startLen = this.pointProjectLength(longeronNormalVec1, longeronOriginVec1, startPntVec);
        let endLen = this.pointProjectLength(longeronNormalVec1, longeronOriginVec1, endPntVec);
        if (startLen < endLen) {
          crossVec.negate();
        }
        params.inwardDirection = crossVec;
      }
    }
  }
  //绘制内矩形框
  async drawInnerRectFrame(params) {
    let sketch = this.command.sketch;
    let drawPoints = [];
    let frameHalfLength = params.frameLength / 2;
    let longeronHalfLength = params.longeronLength / 2;
    let pointY = longeronHalfLength - params.longeronLength * params.zoomRatio;
    let drawFirstPoint = new Point(-frameHalfLength, longeronHalfLength);
    params.drawFirstPoint = drawFirstPoint;
    params.frameHalfLength = frameHalfLength;
    params.longeronHalfLength = longeronHalfLength;
    params.pointY = pointY;//缩放系数Y轴方向的值
    drawPoints.push(drawFirstPoint);//左上角的点
    drawPoints.push(new Point(-frameHalfLength, pointY));//左下角的点
    drawPoints.push(new Point(frameHalfLength, pointY));//右下角的点
    drawPoints.push(new Point(frameHalfLength, longeronHalfLength));//右上角的点
    //创建变量
    await this.command.common.deleteVariableIncrement({variableName: "W1"});
    await this.command.common.createVariableIncrement({
      variableName: "W1",
      variableValue: params.frameLength,
      variableType: ScriptVariableType.Length,
      // description: "框间宽度",
    })
    await this.command.common.deleteVariableIncrement({variableName: "L1"});
    await this.command.common.createVariableIncrement({
      variableName: "L1",
      variableValue: params.longeronLength * params.zoomRatio,
      variableType: ScriptVariableType.Length,
      // description: "第一个长桁到最后一个长桁的距离",
    })
    //第一个长桁和第二个长桁的距离
    await this.command.common.deleteVariableIncrement({variableName: "L3"});
    await this.command.common.createVariableIncrement({
      variableName: "L3",
      variableValue: params.longeronPlaneList[1].length * params.zoomRatio,
      variableType: ScriptVariableType.Length,
      // description: "第一个长桁和第二个长桁的距离",
    })
    //第一个框站位作为基准平面
    //线的绘制顺序：第一条线是左上角-左下角，第二条线是左下角-右下角，第三条线是右下角-右上角，第四条线是右上角-左上角
    let innerRectLines = [];//内矩形框线
    for (let i = 0; i < drawPoints.length; i++) {
      if (i + 1 < drawPoints.length) {
        let lineObject = await sketch.createSketchLineIncrement({
          startPoint: new Point(drawPoints[i].x, drawPoints[i].y),
          endPoint: new Point(drawPoints[i + 1].x, drawPoints[i + 1].y)
        });
        innerRectLines.push(await this.getLine(lineObject));
      } else {
        let lineObject = await sketch.createSketchLineIncrement({
          startPoint: new Point(drawPoints[i].x, drawPoints[i].y),
          endPoint: new Point(drawPoints[0].x, drawPoints[0].y)
        });
        innerRectLines.push(await this.getLine(lineObject));
      }
    }
    params.innerRectLines = innerRectLines;
    //添加固定约束
    if (innerRectLines.length === 4) {
      await sketch.addConstraintListIncrement({
        constraintType: "ConstraintType.FixedPoint",
        firstSnapId: innerRectLines[0].id,
      })
      await sketch.addConstraintListIncrement({
        constraintType: "ConstraintType.FixedPoint",
        firstSnapId: innerRectLines[3].id,
      })
      //创建尺寸约束
      await sketch.createDimensionIncrement({
        firstSnapId: innerRectLines[0].id,
        dimPosition: new Point(-(params.frameLength / 2 + params.horizontalWidth + 50), 0),
        dimVal: "'L1'",
      })
      await sketch.createDimensionIncrement({
        firstSnapId: innerRectLines[1].id,
        dimPosition: new Point(0, pointY - params.verticalWidth - 50),
        dimVal: "'W1'",
      })
    }
  }
  //绘制中间的长桁虚线
  async drawLongeronLine(params) {
    if (params.innerRectLines.length != 4) {
      return;
    }
    let x1 = -params.frameHalfLength - Math.abs(params.frameHalfLength);
    let x2 = params.frameHalfLength + Math.abs(params.frameHalfLength);
    let longeronPntY = params.longeronHalfLength;
    let longeronCount = params.longeronPlaneList.length;
    let lastLine = params.innerRectLines[3];
    let tmpDis = params.frameLength / longeronCount;
    let longeronLen;
    for (let i = 0; i < longeronCount; i++) {
      let longeron = params.longeronPlaneList[i];
      longeronLen = longeron.length * params.zoomRatio;
      longeronPntY = longeronPntY - longeronLen;
      longeron.longeronPointY = longeronPntY;
      //最后一个长桁已绘制，无需再绘。
      let lineEle;
      let refLineRes = await this.command.sketch.createReferenceLineIncrement({
        startPoint: new Point(x1, longeronPntY),
        endPoint: new Point(x2, longeronPntY)
      });
      lineEle = await this.getLine(refLineRes);
      if (lineEle) { //添加名称 显示效果不太好，先屏掉
        // await this.command.sketch.createSketchTextIncrement({elementId: lineEle.id, text: "'" + longeron.name + "'", fontSize: 250});
      }
      if (lastLine && lineEle && i > 0) {
        if (i == 1) {
          await this.command.sketch.createDimensionIncrement({
            firstSnapId: lastLine.id,
            secondSnapId: lineEle.id,
            dimPosition: new Point(-params.frameHalfLength + tmpDis * i, longeronPntY + longeronLen / 2),
            dimVal: "'L3'",
          })
        } else {
          await this.command.sketch.createDimensionIncrement({
            firstSnapId: lastLine.id,
            secondSnapId: lineEle.id,
            dimPosition: new Point(-params.frameHalfLength + tmpDis * i, longeronPntY + longeronLen / 2),
          })
        }
      }
      lastLine = lineEle;
    }
  }
  //绘制外框
  async drawOutFrame(params) {
    let drawPoints = [];
    let outFrameHalfLength = params.frameLength / 2 + parseFloat(params.horizontalWidth);
    let outLongeronHalfLength = params.longeronLength / 2 + parseFloat(params.verticalWidth);
    let pointY = params.pointY;
    if (pointY < 0) {
      pointY = pointY - parseFloat(params.verticalWidth);
    } else {
      pointY = pointY + parseFloat(params.verticalWidth);
    }
    drawPoints.push(new Point(-outFrameHalfLength, outLongeronHalfLength));
    drawPoints.push(new Point(-outFrameHalfLength, pointY));
    drawPoints.push(new Point(outFrameHalfLength, pointY));
    drawPoints.push(new Point(outFrameHalfLength, outLongeronHalfLength));
    await this.createLine(drawPoints);
  }
  //绘制安装孔位点
  async drawHolePoints(params) {
    let sketch = this.command.sketch;
    //安装孔位点的绘制
    // let elementsRes = await this.query.getElementsByFeatureNames(['安装孔位点']);
    // let pointElements = elementsRes?.data?.elements;
    let pointElements = params.installHoleInfoList;
    if (pointElements && pointElements.length > 0) {
      for (let i = 0; i < pointElements.length; i++) {
        let element = pointElements[i].installHolePoint;
        if (!element || (element.type != ElementType.DATUMPOINT && element.type != ElementType.POINT)) {
          continue;
        }
        let pos = element?.params?.position;
        if (!pos) {
          continue;
        }

        let posVec = new THREE.Vector3(pos.x, pos.y, pos.z);
        this.getNearestLongeron(posVec, params);
        let projectFramePos = this.pointProject(params.frameNormal, params.framePos, posVec);//投影到框站位面的点
        let projectLongeronPos = this.pointProject(params.longeronNormal, params.longeronPos, posVec);//投影到长桁站位面的点
        let toFrameLength = projectFramePos.clone().sub(posVec).length().toFixed(5);
        let toLongeronLength = projectLongeronPos.clone().sub(posVec).length().toFixed(5) * params.zoomRatio;
        if (params.reverseDir) {
          toLongeronLength = -toLongeronLength;
        }
        let centerPntX = -params.frameHalfLength + parseFloat(toFrameLength);
        let centerPntY = params.nearLongeron.longeronPointY - toLongeronLength;

        //创建孔
        let holePoint = new THREE.Vector3(centerPntX,centerPntY);
        await this.createHole(holePoint,pointElements[i].holeType);
      }
    }
  }
  async createHole(point2D, holeType = 1) {
    let holeFrameWidth = 50;          //外框宽
    let holeCircleRadius = 20;        //圆半径
    let holeCrossCircleRadius = 0.5;  //内十字圆弧半径
    let holeCrossFrameLength = 7.5;   //内十字框长度
    let offsetDisType2 = 5            //类型2的偏移距离

    //外框定位点
    let pointFrameDL = point2D.clone().add(new THREE.Vector3(-holeFrameWidth / 2, -holeFrameWidth / 2));
    let pointFrameUL = point2D.clone().add(new THREE.Vector3(-holeFrameWidth / 2, holeFrameWidth / 2));
    let pointFrameUR = point2D.clone().add(new THREE.Vector3(holeFrameWidth / 2, holeFrameWidth / 2));
    let pointFrameDR = point2D.clone().add(new THREE.Vector3(holeFrameWidth / 2, -holeFrameWidth / 2));

    //内十字内定位点
    let pointCrossFrameLUI = point2D.clone().add(new THREE.Vector3(-holeCrossCircleRadius, holeCrossCircleRadius));
    let pointCrossFrameLDI = point2D.clone().add(new THREE.Vector3(-holeCrossCircleRadius, -holeCrossCircleRadius));
    let pointCrossFrameRDI = point2D.clone().add(new THREE.Vector3(holeCrossCircleRadius, -holeCrossCircleRadius));
    let pointCrossFrameRUI = point2D.clone().add(new THREE.Vector3(holeCrossCircleRadius, holeCrossCircleRadius));
    //内十字定位点
    let pointCrossFrameLU = point2D.clone().add(new THREE.Vector3(-holeCrossFrameLength, holeCrossCircleRadius));
    let pointCrossFrameLD = point2D.clone().add(new THREE.Vector3(-holeCrossFrameLength, -holeCrossCircleRadius));
    let pointCrossFrameDL = point2D.clone().add(new THREE.Vector3(-holeCrossCircleRadius, -holeCrossFrameLength));
    let pointCrossFrameDR = point2D.clone().add(new THREE.Vector3(holeCrossCircleRadius, -holeCrossFrameLength));
    let pointCrossFrameRD = point2D.clone().add(new THREE.Vector3(holeCrossFrameLength, -holeCrossCircleRadius));
    let pointCrossFrameRU = point2D.clone().add(new THREE.Vector3(holeCrossFrameLength, holeCrossCircleRadius));
    let pointCrossFrameUR = point2D.clone().add(new THREE.Vector3(holeCrossCircleRadius, holeCrossFrameLength));
    let pointCrossFrameUL = point2D.clone().add(new THREE.Vector3(-holeCrossCircleRadius, holeCrossFrameLength));
    //内十字圆弧中心
    let pointCrossCircleCenterL = (pointCrossFrameLD.clone().add(pointCrossFrameLU)).multiplyScalar(0.5);
    let pointCrossCircleCenterR = (pointCrossFrameRD.clone().add(pointCrossFrameRU)).multiplyScalar(0.5);
    let pointCrossCircleCenterD = (pointCrossFrameDL.clone().add(pointCrossFrameDR)).multiplyScalar(0.5);
    let pointCrossCircleCenterU = (pointCrossFrameUL.clone().add(pointCrossFrameUR)).multiplyScalar(0.5);

    if(holeType == 2)
    {
      holeCircleRadius = 16;
      let offsetLineType2L = pointFrameDL.clone().add(new THREE.Vector3(0,offsetDisType2));
      let offsetLineType2R = pointFrameDR.clone().add(new THREE.Vector3(0,offsetDisType2));
      //偏置线
      await this.createSketchLine({startPoint: this.getNewPoint(offsetLineType2L), endPoint: this.getNewPoint(offsetLineType2R)});
    }
    let circlePoint = point2D.clone().add(new THREE.Vector3(holeCircleRadius,0));

    //圆
    await this.createCircle({centerPoint:this.getNewPoint(point2D),circlePoint:this.getNewPoint(circlePoint)});
    //外框
    await this.createSketchLine({startPoint: this.getNewPoint(pointFrameDL), endPoint: this.getNewPoint(pointFrameUL)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointFrameUL), endPoint: this.getNewPoint(pointFrameUR)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointFrameUR), endPoint: this.getNewPoint(pointFrameDR)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointFrameDR), endPoint: this.getNewPoint(pointFrameDL)});
    //十字
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameUL), endPoint: this.getNewPoint(pointCrossFrameLUI)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameLUI), endPoint: this.getNewPoint(pointCrossFrameLU)});
    await this.createArc({centerPoint:this.getNewPoint(pointCrossCircleCenterL),startPoint:this.getNewPoint(pointCrossFrameLU),endPoint:this.getNewPoint(pointCrossFrameLD)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameLD), endPoint: this.getNewPoint(pointCrossFrameLDI)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameLDI), endPoint: this.getNewPoint(pointCrossFrameDL)});
    await this.createArc({centerPoint:this.getNewPoint(pointCrossCircleCenterD),startPoint:this.getNewPoint(pointCrossFrameDL),endPoint:this.getNewPoint(pointCrossFrameDR)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameDR), endPoint: this.getNewPoint(pointCrossFrameRDI)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameRDI), endPoint: this.getNewPoint(pointCrossFrameRD)});
    await this.createArc({centerPoint:this.getNewPoint(pointCrossCircleCenterR),startPoint:this.getNewPoint(pointCrossFrameRD),endPoint:this.getNewPoint(pointCrossFrameRU)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameRU), endPoint: this.getNewPoint(pointCrossFrameRUI)});
    await this.createSketchLine({startPoint: this.getNewPoint(pointCrossFrameRUI), endPoint: this.getNewPoint(pointCrossFrameUR)});
    await this.createArc({centerPoint:this.getNewPoint(pointCrossCircleCenterU),startPoint:this.getNewPoint(pointCrossFrameUR),endPoint:this.getNewPoint(pointCrossFrameUL)});
  }
  getNewPoint(point){
    if(Math.abs(point.x) < 0.001){
      point.x = 0;
    }
    if(Math.abs(point.y) < 0.001){
      point.y = 0;
    }
    if(Math.abs(point.z) < 0.001){
      point.z = 0;
    }

    let newPoint = new Point(point.x,point.y,point.z);
    return newPoint;
  }
  async createCircle(params){
    let circle2DAdd = await this.command.sketch.createCircleIncrement({centerPoint:params.centerPoint,circlePoint:params.circlePoint});
    let circle = await this.getAddElement(circle2DAdd,ElementType.CURVE);
    return circle;
  }
  async createSketchLine(params) {
    let line2DAdd = await this.command.sketch.createSketchLineIncrement({startPoint: params.startPoint, endPoint: params.endPoint});
    let line = await this.getAddElement(line2DAdd,ElementType.CURVE);
    return line;
  }
  async getAddElement(result,type) {
    let element;
    let addElements = result?.data?.modelData?.data?.addElements;
    addElements?.forEach(ele => {
      if (ele.type === type) {
        element = ele;
      }
    })
    return element;
  }
  async createArc(params){
    await this.command.sketch.createArcByCenterIncrement({
      centerPoint: params.centerPoint,
      startPoint: params.startPoint,
      endPoint: params.endPoint
    });
  }
  //绘制开叉中心线
  async drawJagLines(params) {
    for (let i = 0; i < params.jagCenterLines.length; i++) {
      let centerLine = params.jagCenterLines[i];
      if (!centerLine) {
        continue;
      }

      let startPoint = centerLine?.params?.startPoint;
      let endPoint = centerLine?.params?.endPoint;
      if (!startPoint || !endPoint) {
        continue;
      }

      let startPointVec = new THREE.Vector3(startPoint[0], startPoint[1], startPoint[2]);
      let endPointVec = new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2]);
      this.getNearestLongeron(startPointVec, params);
      //起始点
      let projectFrameStartPos = this.pointProject(params.frameNormal, params.framePos, startPointVec);//投影到框站位面的点
      let frameStartLength = projectFrameStartPos.clone().sub(startPointVec).length().toFixed(5);
      //到长桁的距离
      let projectLongeronStartPos = this.pointProject(params.longeronNormal, params.longeronPos, startPointVec);//投影到长桁站位面的点
      let longeronStartLength = projectLongeronStartPos.clone().sub(startPointVec).length().toFixed(5) * params.zoomRatio;
      if (params.reverseDir) {
        longeronStartLength = -longeronStartLength;
      }
      let startPointX = -params.frameHalfLength + parseFloat(frameStartLength);
      let startPointY = params.nearLongeron.longeronPointY - longeronStartLength;
      //终止点
      let projectFrameEndPos = this.pointProject(params.frameNormal, params.framePos, endPointVec);//投影到框站位面的点
      let projectLongeronEndPos = this.pointProject(params.longeronNormal, params.longeronPos, endPointVec);//投影到长桁站位面的点
      let frameEndLength = projectFrameEndPos.clone().sub(endPointVec).length().toFixed(5);
      let longeronEndLength = projectLongeronEndPos.clone().sub(endPointVec).length().toFixed(5) * params.zoomRatio;
      if (params.reverseDir) {
        longeronEndLength = -longeronEndLength;
      }
      let endPointX = -params.frameHalfLength + parseFloat(frameEndLength);
      let endPointY = params.nearLongeron.longeronPointY - longeronEndLength;
      //创建线
      await this.command.sketch.createSketchLineIncrement({
        startPoint: new Point(startPointX, startPointY),
        endPoint: new Point(endPointX, endPointY),
      })
      //创建线外框
      let startPntVec = new THREE.Vector3(startPointX, startPointY);
      let endPntVec = new THREE.Vector3(endPointX, endPointY);
      let dBeveledEdgeLength = params.centerLineDistance * Math.pow(2, 0.5);
      let dir = endPntVec.clone().sub(startPntVec);
      let point1 = this.getOffsetPoint2D(startPntVec, dir.clone().negate(), -45, dBeveledEdgeLength);
      let point2 = this.getOffsetPoint2D(startPntVec, dir.clone().negate(), 45, dBeveledEdgeLength);
      let point3 = this.getOffsetPoint2D(endPntVec, dir, -45, dBeveledEdgeLength);
      let point4 = this.getOffsetPoint2D(endPntVec, dir, 45, dBeveledEdgeLength);
      await this.command.sketch.createSketchLineIncrement({
        startPoint: point1,
        endPoint: point2,
      })
      await this.command.sketch.createSketchLineIncrement({
        startPoint: point2,
        endPoint: point3,
      })
      await this.command.sketch.createSketchLineIncrement({
        startPoint: point3,
        endPoint: point4,
      })
      await this.command.sketch.createSketchLineIncrement({
        startPoint: point4,
        endPoint: point1,
      })
    }
  }
  //生成窗户
  async drawWindow(params) {
    await this.command.common.deleteVariableIncrement({variableName: "A1"});
    await this.command.common.deleteVariableIncrement({variableName: "A2"});
    let pointElements = params.windowPoint;
    if (!pointElements || pointElements.length === 0) {
      return;
    }
    let pointEle = pointElements[0];
    if (!pointEle || (pointEle.type != ElementType.DATUMPOINT && pointEle.type != ElementType.POINT)) {
      return;
    }
    let pos = pointEle?.params?.position;
    if (!pos) {
      return;
    }

    let hDis = 280;//水平距离
    let vDis = 375;//垂直方向的距离
    let circleRadius = 124;//圆弧半径
    let distance = 10;//内外框的距离
    let hLineLength = hDis - circleRadius * 2;//上下水平线的长度
    let vLineLength = vDis - circleRadius * 2;//左右垂直线的长度
    if (circleRadius * 2 > hDis || circleRadius * 2 > vDis) {
      return;
    }

    let A2 = hDis * vLineLength + Math.PI * circleRadius * circleRadius + circleRadius * hLineLength * 2;
    let hDis1 = hDis + distance * 2;
    let circleRadius1 = circleRadius + distance;
    let A1 = hDis1 * vLineLength + Math.PI * circleRadius1 * circleRadius1 + circleRadius1 * hLineLength * 2;
    await this.command.common.createVariableIncrement({
      variableName: "A1",
      variableValue: A1,
      variableType: ScriptVariableType.Length,
      // description: "窗户外框面积",
    })

    await this.command.common.createVariableIncrement({
      variableName: "A2",
      variableValue: A2,
      variableType: ScriptVariableType.Length,
      // description: "窗户内框面积",
    })

    let positionVec = new THREE.Vector3(pos.x, pos.y, pos.z);
    this.getNearestLongeron(positionVec, params);
    let projectLongeronPos = this.pointProject(params.longeronNormal, params.longeronPos, positionVec);//投影到长桁站位面的点
    let toLongeronLength = projectLongeronPos.clone().sub(positionVec).length().toFixed(5) * params.zoomRatio;
    if (params.reverseDir) {
      toLongeronLength = -toLongeronLength;
    }
    let longeronPosY = params.nearLongeron.longeronPointY - toLongeronLength;

    //内框
    let point1 = new Point(-hDis / 2, longeronPosY + vLineLength / 2);
    let point2 = new Point(-hDis / 2, longeronPosY - vLineLength / 2);
    let point3 = new Point(hDis / 2, longeronPosY + vLineLength / 2);
    let point4 = new Point(hDis / 2, longeronPosY - vLineLength / 2);
    let point5 = new Point(-hLineLength / 2, longeronPosY + vDis / 2);
    let point6 = new Point(hLineLength / 2, longeronPosY + vDis / 2);
    let point7 = new Point(-hLineLength / 2, longeronPosY - vDis / 2);
    let point8 = new Point(hLineLength / 2, longeronPosY - vDis / 2);
    await this.createWindow(point1, point2, point3, point4, point5, point6, point7, point8);

    //绘制外框
    point1.x -= distance; point2.x -= distance; point3.x += distance; point4.x += distance;
    point5.y += distance; point6.y += distance; point7.y -= distance; point8.y -= distance;
    await this.createWindow(point1, point2, point3, point4, point5, point6, point7, point8);
  }

  async createWindow(point1, point2, point3, point4, point5, point6, point7, point8) {
    await this.command.sketch.createSketchLineIncrement({
      startPoint: point1,
      endPoint: point2
    });
    await this.command.sketch.createSketchLineIncrement({
      startPoint: point3,
      endPoint: point4
    });
    await this.command.sketch.createSketchLineIncrement({
      startPoint: point5,
      endPoint: point6
    });
    await this.command.sketch.createSketchLineIncrement({
      startPoint: point7,
      endPoint: point8
    });
    //创建圆弧
    //计算圆弧中心点
    await this.command.sketch.createArcByCenterIncrement({
      centerPoint: new Point(point7.x, point2.y),
      startPoint: point2,
      endPoint: point7
    });
    await this.command.sketch.createArcByCenterIncrement({
      centerPoint: new Point(point8.x, point4.y),
      startPoint: point8,
      endPoint: point4
    });
    await this.command.sketch.createArcByCenterIncrement({
      centerPoint: new Point(point6.x, point3.y),
      startPoint: point3,
      endPoint: point6
    });
    await this.command.sketch.createArcByCenterIncrement({
      centerPoint: new Point(point5.x, point1.y),
      startPoint: point5,
      endPoint: point1
    });
  }

  //获取最短距离
  getNearestLongeron(point, params) {
    let planeList = params.longeronPlaneList;
    let minLength = -1;
    let reverseDir = false;
    for (let i = 0; i < planeList.length; i++) {
      let plane = planeList[i];
      let normal = plane?.params?.normal;
      let normalVec = new THREE.Vector3(normal.x, normal.y, normal.z);
      let posVec = this.getPosition(plane);
      let projectPos = this.pointProject(normalVec, posVec, point);//投影到长桁面的点
      let subPos = projectPos.clone().sub(point);//.length().toFixed(5)
      let length = subPos.clone().length().toFixed(5);
      if (minLength === -1 || minLength > parseFloat(length)) {
        minLength = parseFloat(length);
        if (subPos.clone().dot(normalVec) < 0) { //方向相反
          reverseDir = true;
        }
        params.longeronNormal = normalVec;
        params.longeronPos = posVec;
        params.reverseDir = reverseDir;
        params.nearLongeron = plane;
      }
    }
  }

  getOffsetPoint2D(point, dir, iAngle, offset) {
    //x方向
    let mathDirX = new Vector3(1, 0);
    let angle = Math.acos((mathDirX.clone().dot(dir)) / (mathDirX.length() * dir.length())) * 180 / Math.PI;
    let normal = new Vector3(0, 0, 1);
    //两个向量如果同向或者异向，则无正反之分
    if(angle !== 180 && angle !== 0){
      let crossVector = new THREE.Vector3().crossVectors(mathDirX, dir);
      //如果叉乘向量与旋转轴法向点乘小于0，则angle为反向
      if(normal.clone().dot(crossVector) < 0){
        angle = -angle;
      }
    }
    //所求方向与X向的角度
    let resultAngle = angle + iAngle;
    //换算成弧度
    resultAngle = resultAngle * Math.PI / 180;

    let newPoint2D = new Point(point.x + Math.cos(resultAngle) * offset, point.y + Math.sin(resultAngle) * offset);
    return newPoint2D;
  }
  //获取中间的长桁线之间的距离
  async computeLongeronsLength(params, trimSurfaceResult) {
    let face = await this.getFace(trimSurfaceResult);
    if (!face) {
      return;
    }
    let sketch = this.command.sketch;
    //选择两个长桁时通过两端的长桁计算中间的长桁
    // let longeronPlanes = await this.getPlanesBetweenSide(params);
    //添加加强长桁后所需的长桁站位面需要自己手动选择不再进行计算
    let longeronPlanes = await this.getLongeronPlanes(params);
    let sortPlaneList = this.queuePlaneList(longeronPlanes);
    let lastStartPoint = null;
    let longeronLength = 0;
    let intersectLines = [];
    for (let i = 0; i < sortPlaneList.length; i++) {
      let planeEle = sortPlaneList[i];
      //通过该平面求交叉曲线
      await sketch.createSketchIncrement({
        sketchName: '',
        datumId: planeEle.id,
      })
      let intersectCurveRes = await sketch.createIntersectCurveIncrement({
        faceIds: [face.id],
      })
      await sketch.exitSketchIncrement();
      //隐藏草图
      let featureId = this.getFeatureId(intersectCurveRes);
      let res = await this.toolQuery.getEntitiesByFeatureId(featureId);
      if (res && res?.data?.entities?.length > 0) {
        let entityId = res?.data?.entities[0].id;
        await this.command.common.setEntityVisibleIncrement({entityIds:[entityId], status: 0});
      }
      let addElements = intersectCurveRes?.data?.modelData?.data?.addElements;
      if (addElements) {
        for (let j = 0 ; j < addElements.length; j++) {
          let ele = addElements[j];
          if (ele.type === ElementType.CURVE || ele.type === ElementType.EDGE) {
            let elementObj = await this.query.getElementsByIds([ele.id]);
            let elements = elementObj?.data?.elements;
            if (!elements || elements.length === 0) {
              return;
            }
            let startPoint = elements[0]?.params?.startPoint;
            let startPointVec = this.newVectorPnt(startPoint);
            if (!lastStartPoint) {
              lastStartPoint = startPointVec;
            }
            let len = lastStartPoint.clone().sub(startPointVec).length();
            if (planeEle?.isReinforced) {//加强长桁 加宽距离
              len += (params.frameLength / 2);
            }
            if (i > 0 && sortPlaneList[i - 1]?.isReinforced) {
              len += (params.frameLength / 2);
            }
            lastStartPoint = startPointVec;
            planeEle.length = len;
            planeEle.intersectLine = elements[0];
            longeronLength += len;
            break;
          }
        }
      }
    }
    params.longeronLength = longeronLength;
    return sortPlaneList;
  }

  //获取所有的长桁及加强长桁
  getLongeronPlanes(params) {
    let planes = [];
    for (let i = 0; i < params.longerons.length; i++) {
      planes.push(params.longerons[i]);
    }
    for (let i = 0; i < params.reinforcedLongerons.length; i++) {
      let longeron = params.reinforcedLongerons[i];
      longeron.isReinforced = true;
      planes.push(longeron);
    }
    return planes;
  }
  //获取两个长桁间的所有长桁基准面
  async getPlanesBetweenSide(params) {
    if (params.longerons.length < 2) {
      return;
    }
    let betweenPlanes = [];
    let longeron1 = params.longerons[0];
    betweenPlanes.push(longeron1);
    let longeron2 = params.longerons[1];
    let planes = await this.toolQuery.getPlaneAndDatumPlane();
    for (let i = 0; i < planes?.data?.length; i++) {
      let plane = planes.data[i];
      if (!plane || plane.id === longeron1.id || plane.id === longeron2.id) {
        continue;
      }
      if (!this.getPlaneIsInTwoPlane(plane, longeron1, longeron2)) {
        continue;
      }
      betweenPlanes.push(plane);
    }
    betweenPlanes.push(longeron2);
    return betweenPlanes;
  }
  //判断平面是否在两个平面中间
  getPlaneIsInTwoPlane(plane, longeron1, longeron2) {
    let origin = plane?.params?.origin;
    let mathPointOrigin = new THREE.Vector3(origin.x, origin.y, origin.z);
    let origin1 = longeron1?.params?.origin;
    let mathPointOrigin1 = new THREE.Vector3(origin1.x, origin1.y, origin1.z);
    let origin2 = longeron2?.params?.origin;
    let mathPointOrigin2 = new THREE.Vector3(origin2.x, origin2.y, origin2.z);
    let normal1 = longeron1?.params?.normal;
    let mathDir1 = new THREE.Vector3(normal1.x, normal1.y, normal1.z);
    let normal2 = longeron2?.params?.normal;
    let mathDir2 = new THREE.Vector3(normal2.x, normal2.y, normal2.z);
    //处于两个平面中间的平面原点应该为：两侧平面原点指向该平面原点的向量，与两平面法向（互相指向对面平面）应该同向
    let mathDir1To2 = mathPointOrigin2.clone().sub(mathPointOrigin1);
    let mathDir2To1 = mathDir1To2.clone().negate();

    //平面1法向与平面12原点指向是否一致
    let dValue12 = mathDir1To2.clone().dot(mathDir1);
    //不一致则进行翻转
    if(dValue12 < 0)
    {
      mathDir1 = mathDir1.clone().negate();
    }
    //平面2法向与平面21原点指向是否一致
    let dValue21 = mathDir2To1.clone().dot(mathDir2);
    //不一致则进行翻转
    if(dValue21 < 0)
    {
      mathDir2 = mathDir2.clone().negate();
    }

    //两平面原点到平面的原点
    let math1To0 = mathPointOrigin.clone().sub(mathPointOrigin1);
    let math2To0 = mathPointOrigin.clone().sub(mathPointOrigin2);

    //如果平面法向与限制平面原点到平面原点的向量均符合>0则该平面符合条件
    if(math1To0.clone().dot(mathDir1) > 0 && math2To0.clone().dot(mathDir2) > 0)
    {
      return true;
    }

    return false;
  }

  //长桁排序
  queuePlaneList(planeList) {
    if (planeList.length <= 0) {
      return;
    }
    //第一个长桁与其它长桁的交点
    let plane = planeList[0];
    let origin = plane?.params?.origin;
    let normal = plane?.params?.normal;
    let originVec = new THREE.Vector3(origin.x, origin.y, origin.z);
    let normalVec = new THREE.Vector3(normal.x, normal.y, normal.z);
    for (let i = 0; i < planeList.length; i++) {
      let longeron = planeList[i];
      let longeronOrigin = longeron?.params?.origin;
      let longeronNormal = longeron?.params?.normal;
      let longeronOriginVec = new THREE.Vector3(longeronOrigin.x, longeronOrigin.y, longeronOrigin.z);
      let longeronNormalVec = new THREE.Vector3(longeronNormal.x, longeronNormal.y, longeronNormal.z);
      let intersectPnt = this.getIntersectPoint(originVec, normalVec, longeronOriginVec, longeronNormalVec);
      longeron.intersectPoint = intersectPnt;
    }
    let firstPoint = this.getIntersectPoint(originVec, normalVec, originVec, normalVec);
    planeList.sort((plane1, plane2) => {
      let length1 = firstPoint.clone().sub(plane1.intersectPoint).length();
      let length2 = firstPoint.clone().sub(plane2.intersectPoint).length();
      if (length1 < length2) {
        return -1;
      } else if (length1 > length2) {
        return 1;
      } else {
        return 0;
      }
    })
    // intersectPointList.sort((point1, point2) => {
    //   let length1 = firstPoint.clone().sub(point1).length();
    //   let length2 = firstPoint.clone().sub(point2).length();
    //   if (length1 < length2) {
    //     return -1;
    //   } else if (length1 > length2) {
    //     return 1;
    //   } else {
    //     return 0;
    //   }
    // });

    // let modifyPointList = intersectPointList;
    // for (let i = 1; i < intersectPointList.length; i++) {
    //   let minLength = firstPoint.clone().sub(intersectPointList[i]).length();
    //   let planeTmp = planeList[i];
    //   let index = 1;
    //   for (let j = 1; j < modifyPointList.length; j++) {
    //     let lenTmp = firstPoint.clone().sub(modifyPointList[j]).length();
    //     if (lenTmp < minLength) {
    //       minLength = lenTmp;
    //       index = j;
    //     }
    //   }
    //   if (i != index) {
    //     planeList[i] = planeList[index];
    //     planeList[index] = planeTmp;
    //     modifyPointList.splice(index, 1);
    //   }
    // }
    return planeList;
  }

  compareVector(a, b) {
    let diff = a.clone().sub(b).length();
    return diff;
  }
  getIntersectPoint(linePoint,lineDir,planePoint,planeNormal){
    //判断直线不与平面平行
    if(lineDir.clone().dot(planeNormal) === 0){
      return;
    }
    lineDir.normalize();

    //直线上点在平面的投影
    let linePointProject = this.pointProject(planeNormal,planePoint,linePoint);
    //直线点到直线点投影的向量
    let vectLinePointToProject = linePointProject.clone().sub(linePoint);
    //直线点到直线点投影的距离
    let length = vectLinePointToProject.clone().length();

    vectLinePointToProject.normalize();

    //直线方向与法向的夹角
    let alpha = Math.acos(vectLinePointToProject.clone().dot(lineDir));
    //交点在直线点上的偏移
    let vectOffsetDis = length / Math.cos(alpha);

    //交点
    let intersectPoint = linePoint.clone().add(lineDir.clone().multiplyScalar(vectOffsetDis));
    return intersectPoint;
  }
  //投影到平面上的三维点
  pointProject(dir,origin,point){
    let pointToOrigin = origin.clone().sub(point);
    let dirNor = dir.clone().normalize();
    let oriNor = pointToOrigin.clone().normalize();
    let alpha = Math.acos(dirNor.clone().dot(oriNor));
    let projectDis = pointToOrigin.length() * Math.cos(alpha);
    let projectPoint = point.clone().add(dirNor.clone().multiplyScalar(projectDis));
    return projectPoint;
  }
  //投影到平面的距离
  pointProjectLength(dir, origin, point) {
    //投影到平面的三维点
    let pointProject = this.pointProject(dir,origin,point);
    //投影距离
    let length = pointProject.clone().sub(point).length().toFixed(5);
    return length;
  }
  getPosition(element) {
    let position;
    if (element.type === ElementType.FACE) {
      position = element?.params?.position;
    } else if (element.type === ElementType.DATUMPLANE) {
      position = element?.params?.origin;
    }
    let posVec = new THREE.Vector3(position.x, position.y, position.z)
    return posVec;
  }

  convertPoint3DToPoint2D(datum, point3D) {
    let datumMatrix = this.getDatumPlaneMatrix(datum);
    let point2D = point3D.clone().applyMatrix4(datumMatrix.clone().invert());
    if (Math.abs(point2D.x) < 0.001) {
      point2D.x = 0;
    }
    if (Math.abs(point2D.y) < 0.001) {
      point2D.y = 0;
    }
    return new Point(point2D.x, point2D.y);
  }
  getDatumPlaneMatrix(datum) {
    if (datum) {
      let normal = datum.params.normal;
      let direction = datum.params.xDirection;
      let xDir = new THREE.Vector3(direction.x, direction.y, direction.z);
      let zDir = new THREE.Vector3(normal.x, normal.y, normal.z);
      let yDir = new THREE.Vector3().crossVectors(zDir, xDir);
      let origin = datum.params.origin;
      //获取三个方向
      let sectionMatrix = new THREE.Matrix4();
      sectionMatrix.makeBasis(xDir, yDir, zDir);
      sectionMatrix.setPosition(origin.x, origin.y, origin.z);
      return sectionMatrix;
    } else {
      return null;
    }
  }
  async createLine(drawPoints) {
    for (let i = 0; i < drawPoints.length; i++) {
      if (i + 1 < drawPoints.length) {
        await this.command.sketch.createSketchLineIncrement({
          startPoint: new Point(drawPoints[i].x, drawPoints[i].y),
          endPoint: new Point(drawPoints[i + 1].x, drawPoints[i + 1].y)
        });
      } else {
        await this.command.sketch.createSketchLineIncrement({
          startPoint: new Point(drawPoints[i].x, drawPoints[i].y),
          endPoint: new Point(drawPoints[0].x, drawPoints[0].y)
        });
      }
    }
  }
  //////////////////////////////////////
  //以下是隔热隔声紧固件实例化的相关方法
  //
  async fastenerInstantiation(params) {
    this.projectId = await this.getProjectId();
    let elements = params.elements;
    if (!this.projectId || elements.length === 0) {
      return;
    }
    let names = "";
    for (let i = 0; i < elements.length; i++) {
      if (!elements[i]?.selectName) {
        continue;
      }
      let element = elements[i]
      let ret = await this.insertComponent(element);
      if (!ret) {
        if (names != "") {
          names += ",";
        }
        names += element.selectName;
      }
    }
    if (names != "") {
      this.eventBusAlertMsg("名称为 " + names + " 的紧固件模板未找到！", "warning");
    }
  }
  async insertComponent(element) {
    let startPnt = element.params.startPoint;
    let endPnt = element.params.endPoint;
    let middlePnt = element.params.middlePoint;
    if (startPnt?.length != 3 || endPnt?.length != 3) {
      return false;
    }
    // let point1Vec = new Vector3(startPnt[0], startPnt[1], startPnt[2]);
    // let point2Vec = new Vector3(endPnt[0], endPnt[1], endPnt[2]);
    // let length = point2Vec.clone().sub(point1Vec).length();
    let MatrixRequest = {
      "partStart": [0, 0, 0],
      "partEnd": [1, 0, 0],
      "assemblyStart": [startPnt[0], startPnt[1], startPnt[2]],
      "assemblyEnd": [endPnt[0], endPnt[1], endPnt[2]]
    }
    let mat = await this.transformMatrix(MatrixRequest);
    let matrix = new Matrix4();
    matrix.set(...mat);
    let insertRes = await this.command.assembly.insertComponentIncrement({
      docName: element.selectName,
      matrix4: matrix,
      boxCenter: 0,
      projectId: this.projectId,
    });
    let instances = insertRes?.data?.modelData?.data?.addInstances;
    if (!instances || instances.length === 0) {
      return false;
    }
    return true;
    let instanceId = instances[0].id;
    // // let entityDataRes = await this.query.getEntitiesByInstanceId(instanceId);
    // // let entityIds = entityDataRes?.data?.entities?.map(ent => ent.id);
    let elementsRes = await this.query.getElementsByInstanceId(instanceId);
    let tmpElements = elementsRes?.data?.elements;
    let pointEle = tmpElements?.find(ele => ele.type === ElementType.DATUMPOINT);
    if (!pointEle) {
      return false;
    }
    let insertPartPos = pointEle?.params?.position;
    // await this.moveInstance(instanceId, pos, middlePnt);
    // await this.rotateInstance(instanceId, startPnt, endPnt);
    if (instances && instances.length > 0) {
      let addIns = instances[0];
      // await this.updateMatrix(addIns, middlePnt, endPnt);

      // await this.command.assembly.insertComponentIncrement({
      //   docName: element.selectName,
      //   matrix4: matrix2,
      //   boxCenter: 1,
      //   projectId: this.projectId,
      // });

      // await this.command.assembly.createMatingIncrement({
      //   moveInstanceId: addIns.id,
      //
      // });
    }

  }

  async getProjectId() {
    let res = await this.toolQuery.getProjectInfo();
    return res?.data?.projectInfo?.projectId;
  }
  //移动模型
  async moveInstance(instanceId, startPnt, endPnt) {
    await this.command.assembly.moveInstanceIncrement({
      instanceId: [instanceId],
      startPos: new Point(startPnt[0], startPnt[1], startPnt[2]),
      endPos: new Point(0,0,0),
      moveType: 3,
      checkType: 0,
      varX: endPnt[0],
      varY: endPnt[1],
      varZ: endPnt[2],
    });
  }
  //旋转模型
  async rotateInstance(entityIds, startPnt, endPnt) {
    let fastenerNormal = new THREE.Vector3(0, 0, 1);
    let point1Vec = new Vector3(startPnt[0], startPnt[1], startPnt[2]);
    let point2Vec = new Vector3(endPnt[0], endPnt[1], endPnt[2]);
    let lineDir = point2Vec.clone().sub(point1Vec);
    let rad = fastenerNormal.clone().angleTo(lineDir);
    let angleValue = THREE.MathUtils.radToDeg(rad);
    if (angleValue === 0) {
      //不进行旋转操作
      return;
    }
    // 旋转轴
    let axialDir = new THREE.Vector3();
    // 两向量的法向（叉乘）
    axialDir.crossVectors(fastenerNormal, lineDir);
    axialDir.normalize();
    if (axialDir.length() < 0.0001) {
      axialDir = fastenerNormal.clone();
      // if (params.reverseDir) {
      //   axialDir.subScalar(-1);
      // }
    }
    let direction = new Direction();
    direction.setPoint(new Point(),new Point(axialDir.x,axialDir.y,axialDir.z));
    await this.command.solid.createTransformByRotateIncrement({
      entityIds: entityIds,
      copy: 0,
      angle: angleValue,
      axis: direction,
      reverse: 0,
    })
  }
  //更新矩阵信息
  async updateMatrix(addIns, middlePnt, endPnt) {
    let elementsRes = await this.query.getElementsByInstanceId(addIns.id);
    let tmpElements = elementsRes?.data?.elements;
    let pointEle = tmpElements?.find(ele => ele.type === ElementType.DATUMPOINT);
    let curveEle = tmpElements?.find(ele => ele.type === ElementType.CURVE);
    let startPoint = curveEle?.params?.middlePoint;
    let endPoint = curveEle?.params?.endPoint;
    if (!pointEle) {
      return;
    }
    let insertPartPos = pointEle?.params?.position;
    let matrixData;
    if (startPoint && endPoint) {
      matrixData = {
        "partStart": [startPoint[0], startPoint[1], startPoint[2]],
        "partEnd": [endPoint[0], endPoint[1], endPoint[2]],
        "assemblyStart": [middlePnt[0], middlePnt[1], middlePnt[2]],
        "assemblyEnd": [endPnt[0], endPnt[1], endPnt[2]]
      }
    } else {
      matrixData = {
        "partStart": [insertPartPos.x, insertPartPos.y, insertPartPos.z],
        "partEnd": [insertPartPos.x, insertPartPos.y + 4, insertPartPos.z],
        "assemblyStart": [middlePnt[0], middlePnt[1], middlePnt[2]],
        "assemblyEnd": [endPnt[0], endPnt[1], endPnt[2]]
      }
    }
    let mat2 = await this.transformMatrix2(matrixData);
    await this.toolQuery.updateInstanceMatrix({instanceId: addIns.id, matrix: mat2});
  }
  async transformMatrix(MatrixRequest) {
    try {
      let config = {
        timeout: 15000,
        headers: {
          'Content-Type': 'application/json'
        }
      };

      let url = 'fastener/transformMatrix';
      let response = await request.post(url, MatrixRequest, config)
      return response.data
    } catch (error) {
      console.error('调用失败:', error.response ? error.response.data : error.message);
    }
  }
  async transformMatrix2(data) {
    try {
      let config = {
        timeout: 15000,
        headers: {
          'Content-Type': 'application/json'
        }
      };

      let url = 'fastener/transformMatrix2';
      let response = await request.post(url, data, config)
      return response.data
    } catch (error) {
      console.error('调用失败:', error.response ? error.response.data : error.message);
    }
  }
  //设置特征显隐
  async setFeatureVisible(featureId, visible = false) {
    let res = await this.toolQuery.getEntitiesByFeatureId(featureId);
    if (res && res?.data?.entities?.length > 0) {
      let entityId = res?.data?.entities[0].id;
      let status = visible ? 1 : 0;
      await this.command.common.setEntityVisibleIncrement({entityIds: [entityId], status:status });
    }
  }

  //获取线的哪个端点在平面上
  getStartOrEndOnPlane(guideCurve,planeOrigin,planeNormal){
    let startPoint = this.getThreeVector3(guideCurve.params.startPoint);
    let endPoint = this.getThreeVector3(guideCurve.params.endPoint);

    let disStart = this.getDisFromPointToPlane(planeOrigin,planeNormal,startPoint);
    let disEnd = this.getDisFromPointToPlane(planeOrigin,planeNormal,endPoint);

    let res = -1;
    if(Math.abs(disStart) < 0.001){
      res = 0;
    }else if(Math.abs(disEnd) < 0.001){
      res = 1;
    }
    return res;
  }
  getThreeVector3(object){
    let vector3 = new THREE.Vector3();
    if(object.x){
      vector3.x = object.x;
    }else if(object[0]){
      vector3.x = object[0];
    }
    if(object.y){
      vector3.y = object.y;
    }else if(object[1]){
      vector3.y = object[1];
    }
    if(object.z){
      vector3.z = object.z;
    }else if(object[2]){
      vector3.z = object[2];
    }
    return vector3;
  }
  //计算点到平面的距离,根据平面法向有正负之分
  getDisFromPointToPlane(planePoint,planeNormal,point){
    planeNormal.normalize();
    let originToPoint = point.clone().sub(planePoint);
    let dis = planeNormal.clone().dot(originToPoint);
    return dis;
  }
  //根据线端点创建一个点
  async createPointByCurve(curve,dOffsetPercentage = 0) {
    let originPoint = await this.command.datum.createPointByCurveIncrement({
      referenceEntities: curve.id,
      multiplePntsType: 1,
      referenceValue: dOffsetPercentage
    });
    let featureId = this.getFeatureId(originPoint);
    let pointElementsRes = await this.query.getElementsByFeatureId(featureId);
    let pointElements = pointElementsRes?.data?.elements;
    let pointId;
    if (pointElements) {
      for (let i = 0; i < pointElements.length; i++) {
        if (pointElements[i].type === ElementType.DATUMPOINT) {
          pointId = pointElements[i].id;
          break;
        }
      }
    }
    return pointId;
  }
  //科学计数法处理
  dealValue(value){
    if(Math.abs(value) < 0.001){
      value = 0;
    }
    return value;
  }
}

const heatAndSoundInsulationCmd = new HeatAndSoundInsulationCommand();
export { heatAndSoundInsulationCmd }